package cn.HuanG.user.service.impl;

import cn.HuanG.base.exception.BusinessException;
import cn.HuanG.base.service.impl.BaseServiceImpl;
import cn.HuanG.user.domain.LoginInfo;
import cn.HuanG.user.domain.User;
import cn.HuanG.user.domain.dto.UserDTO;
import cn.HuanG.user.mapper.LoginInfoMapper;
import cn.HuanG.user.mapper.UserMapper;
import cn.HuanG.user.service.IUserService;
import cn.HuanG.util.MD5Utils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    @Override
    public void register(UserDTO userDTO) {
        //验证数据的准确性
        verifyData(userDTO);//没有抛异常  数据是正确的
        //创建logininfo对象
        LoginInfo loginInfo = userDTO2LoginInfo(userDTO);
        //保存到数据库里面
        //保存到 t_loginInfo
        loginInfoMapper.save(loginInfo);
        //将logininfo转换成user
        User user = LoginInfo2User(loginInfo);
        //保存到 t_user
        userMapper.save(user);


    }

    private User LoginInfo2User(LoginInfo loginInfo) {
        User user = new User();
        //将数据copy到user
        BeanUtils.copyProperties(loginInfo,user);
        //需要手动处理的部分字段
        user.setState(1);
        user.setCreatetime(new Date());
        user.setLogininfo_id(loginInfo.getId());

        return user;
    }

    private LoginInfo userDTO2LoginInfo(UserDTO userDTO) {
        LoginInfo loginInfo = new LoginInfo();
        //将前台获取的user表中phone设置到logininfo表中
        loginInfo.setPhone(userDTO.getPhone());
        //将状态默认设置为1
        loginInfo.setDisable(1);
        //设置用户类型
        loginInfo.setType(1);
        //为保证密码安全，获取一个随机数【盐】,再将其转为stringleix
        String salt = UUID.randomUUID().toString();
        //将随机数拼接到密码后面并且加密
        String md5 = MD5Utils.encrypByMd5(userDTO.getPassword() + salt);
        //将加密的密码和salt保存在logininfo数据库
        loginInfo.setSalt(salt);
        loginInfo.setPassword(md5);
        return loginInfo;
    }

    private void verifyData(UserDTO userDTO) {
        //1.当前手机号是否注册
        User user =userMapper.loadByPhone(userDTO.getPhone());
        if (user!=null){
            throw new BusinessException("手机号已经注册，请直接登录");
        }
        //2.验证两次密码是否一致
        if(!userDTO.getPassword().equals(userDTO.getPasswordRepeat())){
            throw new BusinessException("两次密码不一致");
        }
        //3.验证码是否正确

        //通过手机号获取数据，如果数据库存在数据则表示用户注册过
        String codeInRedis = (String) redisTemplate.opsForValue().get(userDTO.getPhone()+":REGISTER");
        if (codeInRedis==null||userDTO.getCode()==null){
            throw new BusinessException("验证码已经过期，请重新获取");
        }
        if(!userDTO.getCode().equals(codeInRedis.split(":")[0])){
            throw new BusinessException("验证码输入错误，请核对");
        }

    }

}
